package es

import (
	"context"
	"gopkg.in/olivere/elastic.v5"
	"strings"
)

// 创建index的选项
type CreateIndexOption func(*elastic.IndicesCreateService)

// 设置index的mapping
func Mapping(mapping string) CreateIndexOption {
	return func(cs *elastic.IndicesCreateService) {
		cs.BodyString(mapping)
	}
}

// 创建index
func (e *EsClient) CreateIndex(index string, options ...CreateIndexOption) (err error) {
	ctx := context.Background()
	cs := e.rawClient.CreateIndex(index)
	for _, option := range options {
		option(cs)
	}
	_, err = cs.Do(ctx)
	if err != nil {
		return err
	}
	return
}

// 打开index
func (e *EsClient) OpenIndex(index string) (err error) {
	_, err = e.rawClient.OpenIndex(index).Do(context.TODO())
	return
}

// 关闭index
func (e *EsClient) CloseIndex(index string) (err error) {
	_, err = e.rawClient.CloseIndex(index).Do(context.TODO())
	return
}

// 删除index
func (e *EsClient) DeleteIndex(index string) (err error) {
	_, err = e.rawClient.DeleteIndex(strings.Split(index, ",")...).Do(context.TODO())
	return
}

// 滚动index
func (e *EsClient) RolloverIndex(alias, index string, conditions map[string]interface{}) (res interface{}, err error) {
	res, err = e.rawClient.RolloverIndex(alias).NewIndex(index).Conditions(conditions).Do(context.TODO())
	return
}

// Segments index (分段)
func (e *EsClient) SegmentsIndex(index string) (res interface{}, err error) {
	res, err = e.rawClient.IndexSegments(index).Do(context.TODO())
	return
}

// Shrink index (缩小)
func (e *EsClient) ShrinkIndex(source, target, mapping string) (res interface{}, err error) {
	res, err = e.rawClient.ShrinkIndex(source, target).BodyString(mapping).Do(context.TODO())
	return
}

// 统计index
func (e *EsClient) StatsIndex(index string, metrics string) (res interface{}, err error) {
	res, err = e.rawClient.IndexStats(strings.Split(index, ",")...).Metric(strings.Split(metrics, ",")...).Do(context.TODO())
	return
}

// 复制index
func (e *EsClient) ReIndex(index, reindex string) (res interface{}, err error) {
	src := elastic.NewReindexSource().Index(index)
	dst := elastic.NewReindexDestination().Index(reindex)
	res, err = e.rawClient.Reindex().Source(src).Destination(dst).Do(context.TODO())
	return
}

// 判断index是否存在
func (e *EsClient) IsIndexExist(index string) (exist bool, err error) {
	return e.rawClient.IndexExists(index).Do(context.TODO())
}

// 获取所有 index 名称
func (e *EsClient) IndexNames() (res []string, err error) {
	return e.rawClient.IndexNames()
}

// 获取 索引别名
func (e *EsClient) Aliases(index string) (res interface{}, err error) {
	return e.rawClient.Aliases().Index(strings.Split(index, ",")...).Do(context.TODO())
}

// 添加索引别名
func (e *EsClient) AddAliases(alias, index string) (res interface{}, err error) {
	return e.rawClient.Alias().Action(elastic.NewAliasAddAction(alias).Index(strings.Split(index, ",")...)).Do(context.TODO())
}

// 移除索引别名
func (e *EsClient) RemoveAliases(alias, index string) (res interface{}, err error) {
	return e.rawClient.Alias().Action(elastic.NewAliasRemoveAction(alias).Index(strings.Split(index, ",")...)).Do(context.TODO())
}

// 获取词语分析
func (e *EsClient) GetAnalyze(text string, analyzer string) (res interface{}, err error) {
	return e.rawClient.IndexAnalyze().Text(text).Analyzer(analyzer).Do(context.TODO())
}

// Flush 索引
func (e *EsClient) FlushIndex(index string) (res interface{}, err error) {
	return e.rawClient.Flush(strings.Split(index, ",")...).Do(context.TODO())
}

// refresh 刷新索引
func (e *EsClient) RefreshIndex(index string) (res interface{}, err error) {
	return e.rawClient.Refresh(index).Do(context.TODO())
}

// 获取 Settings
func (e *EsClient) GetSetting(index string) (res interface{}, err error) {
	return e.rawClient.IndexGetSettings(strings.Split(index, ",")...).Do(context.TODO())
}

// 插入 Settings
func (e *EsClient) PutSettings(index, mapping string) (res interface{}, err error) {
	return e.rawClient.IndexPutSettings().Index(index).BodyString(mapping).Do(context.TODO())
}

// 获取 Mapping
func (e *EsClient) GetMapping(index string) (res interface{}, err error) {
	return e.rawClient.GetMapping().Index(strings.Split(index, ",")...).Do(context.TODO())
}

// 插入 Mapping
func (e *EsClient) PutMapping(index, mapping string) (res interface{}, err error) {
	return e.rawClient.PutMapping().Index(index).BodyString(mapping).Do(context.TODO())
}

// 获取 Field Mapping
func (e *EsClient) GetFieldMapping(index string) (res interface{}, err error) {
	return e.rawClient.GetFieldMapping().Index(strings.Split(index, ",")...).Do(context.TODO())
}

// 获取index
func (e *EsClient) Model(index string) *Model {
	return newModel(index, e)
}